package com.bookworld.service;

import com.bookworld.model.User;
import com.bookworld.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserDao userDao;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    public User findById(Long id) {
        return userDao.findById(id);
    }
    
    public User findByUsername(String username) {
        return userDao.findByUsername(username);
    }
    
    public User findByEmail(String email) {
        return userDao.findByEmail(email);
    }
    
    public User findByUsernameOrEmail(String username, String email) {
        return userDao.findByUsernameOrEmail(username, email);
    }
    
    public List<User> findByActive(Boolean active) {
        return userDao.findByActive(active);
    }
    
    public List<User> findAllWithPagination(int page, int size) {
        int offset = (page - 1) * size;
        return userDao.findAllWithPagination(size, offset);
    }
    
    public List<User> search(String keyword) {
        return userDao.search(keyword);
    }
    
    public User register(User user) {
        // 检查用户名是否已存在
        if (userDao.findByUsername(user.getUsername()) != null) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (userDao.findByEmail(user.getEmail()) != null) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 设置默认值
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setActive(true);
        user.setBalance(BigDecimal.ZERO);
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());
        
        userDao.insert(user);
        return user;
    }
    
    public User update(User user) {
        User existingUser = userDao.findById(user.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查用户名是否被其他用户使用
        User userByUsername = userDao.findByUsername(user.getUsername());
        if (userByUsername != null && !userByUsername.getId().equals(user.getId())) {
            throw new RuntimeException("用户名已被使用");
        }
        
        // 检查邮箱是否被其他用户使用
        User userByEmail = userDao.findByEmail(user.getEmail());
        if (userByEmail != null && !userByEmail.getId().equals(user.getId())) {
            throw new RuntimeException("邮箱已被使用");
        }
        
        // 如果密码为空，保持原密码
        if (user.getPassword() == null || user.getPassword().isEmpty()) {
            user.setPassword(existingUser.getPassword());
        } else {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        
        user.setUpdatedAt(LocalDateTime.now());
        userDao.update(user);
        return user;
    }
    
    public void updateActiveStatus(Long id, Boolean active) {
        userDao.updateActiveStatus(id, active);
    }
    
    public void updateBalance(Long id, BigDecimal amount) {
        userDao.updateBalance(id, amount);
    }
    
    public void delete(Long id) {
        userDao.delete(id);
    }
    
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        User user = userDao.findById(userId);
        if (user == null) {
            return false;
        }
        
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            return false;
        }
        
        user.setPassword(passwordEncoder.encode(newPassword));
        user.setUpdatedAt(LocalDateTime.now());
        userDao.update(user);
        return true;
    }
    
    public boolean resetPassword(String email, String newPassword) {
        User user = userDao.findByEmail(email);
        if (user == null) {
            return false;
        }
        
        user.setPassword(passwordEncoder.encode(newPassword));
        user.setUpdatedAt(LocalDateTime.now());
        userDao.update(user);
        return true;
    }
    
    public int count() {
        return userDao.count();
    }
    
    public int countByActive(Boolean active) {
        return userDao.findByActive(active).size();
    }
    
    public boolean existsByUsername(String username) {
        return userDao.findByUsername(username) != null;
    }
    
    public boolean existsByEmail(String email) {
        return userDao.findByEmail(email) != null;
    }
}
